﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace Kimd.Common
{
    public class XmlSerializerHelper<T> where T : class, new()
    {
        public static XmlNode SerializeToXmlNode(T TObj)
        {
            try
            {
                XmlWriterSettings set = new XmlWriterSettings();
                set.Indent = true;
                StringWriter sw = new StringWriter();
                using (XmlWriter writer = XmlWriter.Create(sw, set))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    serializer.Serialize(writer, TObj);
                }
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(sw.GetStringBuilder().ToString());
                return doc.DocumentElement;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static T DeserializeFromXmlNode(XmlNode node)
        {
            try
            {
                StringReader sr = new StringReader(node.OuterXml);
                using (XmlReader reader = XmlReader.Create(sr))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(reader) as T;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static string SerializeToString(T TObj)
        {
            try
            {
                XmlWriterSettings set = new XmlWriterSettings();
                set.Indent = true;
                StringWriter sw = new StringWriter();
                using (XmlWriter writer = XmlWriter.Create(sw, set))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    serializer.Serialize(writer, TObj);
                }
                return sw.GetStringBuilder().ToString();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static T DeserializeFromString(string str)
        {
            try
            {
                StringReader sr = new StringReader(str);
                using (XmlReader reader = XmlReader.Create(sr))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(reader) as T;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static T DeserializeFromFile(string filename)
        {
            try
            {
                if (!File.Exists(filename))
                    return new T();
                using (FileStream fs = new FileStream(filename, FileMode.Open))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(fs) as T;
                }
                //using (FileStream fileStream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read))
                //{
                //    BinaryFormatter b = new BinaryFormatter();
                //    return b.Deserialize(fileStream) as T;
                //}
            }
            catch (Exception ex)
            {
                //throw ex;
                return null;
            }
        }
        public static void SerializeToFile(T obj, string filename)
        {
            try
            {
                FileInfo fi = new FileInfo(filename);
                if (!Directory.Exists(fi.DirectoryName))
                {
                    Directory.CreateDirectory(fi.DirectoryName);
                }
                using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        XmlSerializer xs = new XmlSerializer(typeof(T));
                        xs.Serialize(sw, obj);
                    }
                }
                //using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
                //{
                //    BinaryFormatter b = new BinaryFormatter();
                //    b.Serialize(fs, obj);
                //}
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public static XmlNode XmlSerialize(T entity)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            StringBuilder sb = new StringBuilder();
            try
            {
                using (XmlWriter writer = XmlWriter.Create(sb))
                {
                    serializer.Serialize(writer, entity, null);
                    XmlDocument xmldoc = new XmlDocument();
                    xmldoc.LoadXml(sb.ToString());
                    return xmldoc.DocumentElement;
                }
            }
            catch (Exception ex)
            {

                return null;
            }
        }
        public static T Deserialize(XmlNode xmlNode)
        {
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                using (XmlReader reader = new XmlTextReader(new StringReader(xmlNode.InnerXml)))
                {
                    return (T)serializer.Deserialize(reader);
                }
            }
            catch (Exception ex)
            {
                return default(T);
            }
        }

    }
}
